package com.demo.user;

import java.security.NoSuchAlgorithmException;
import java.security.spec.InvalidKeySpecException;
import java.util.Date;
import java.util.List;

import org.apache.commons.codec.binary.Base64;

import com.common.dto.ReturnDto;
import com.common.interceotpr.AuthInterceptor;
import com.common.util.ConstantInit;
import com.common.util.ToolPbkdf2;
import com.demo.common.model.User;
import com.jfinal.aop.Before;
import com.jfinal.core.Controller;
import com.jfinal.kit.PropKit;
import com.jfinal.kit.StrKit;
import com.jfinal.log.Log;
import com.jfinal.plugin.activerecord.tx.Tx;

public class UserController extends Controller {

	private static final Log log = Log.getLog(UserController.class);
	
	@Before(UsernameValitor.class)
	public void save() {
		ReturnDto rdto = new ReturnDto();
		try {
			User user = getModel(User.class);
			byte[] salt = ToolPbkdf2.generateSalt();
			byte[] encryptedPassword = ToolPbkdf2.getEncryptedPassword(user.getPassword(), salt);
			ToolPbkdf2.getEncryptedPassword(user.getPassword(), salt);
			user.setSalt(Base64.encodeBase64String(salt));
			user.setPassword(Base64.encodeBase64String(encryptedPassword));
			user.setErrorcount(0);
			user.setStatus(1);
			if(user.save()) {
				rdto.setSuccess(true);
				rdto.setMsg("注册成功!");
			} else {
				rdto.setSuccess(false);
				rdto.setErrMsg("注册失败!");
			}
		} catch (NoSuchAlgorithmException e) {
			log.error(e.getMessage());
			rdto.setErrMsg(e.getMessage());
			rdto.setSuccess(false);
		} catch (InvalidKeySpecException e) {
			log.error(e.getMessage());
			rdto.setErrMsg(e.getMessage());
			rdto.setSuccess(false);
		}  finally {
			renderJson(rdto);
		}
	}
	
	//检查用户名是否重复
	public void checkUsername() {
		String username = getPara("username");
		if(StrKit.notBlank(username)) {
			int userNum = User.dao.findByUsername(username).size();
			if(userNum > 0)
				renderText("false");
			else
				renderText("true");
			return;
		}
		renderText("false");
	}
	
	//用户登陆
	@Before({LoginValidator.class, Tx.class})
	public void login() {
		ReturnDto rtDto = new ReturnDto();
		
		try {
			User tmp = getModel(User.class);
			//1.取用户
			List<User> list = User.dao.findByUsername(tmp.getUsername());
			if(list != null && list.size() == 1) {
				User user = list.get(0);
				
				//2.判断是否为停用账户
				if (0 == user.getStatus()) {
					throw new IllegalArgumentException("该用户已被停用,具体原因请咨询管理员!");
				}
				
				//3.密码错误次数超限
				if(user.getErrorcount() >= PropKit.getInt("errorNum")) {
					Date stopDate = user.getStopDate();
					if((new Date().getTime() - stopDate.getTime())/3600000 > PropKit.getInt("passErrorHour")) {
						throw new IllegalArgumentException("密码错误次数超过限制," +  PropKit.getInt(ConstantInit.config_passErrorCount_key) + "小时内不允许登陆!");
					}
				} else {
					user.setErrorcount(0);
					user.setStatus(1);
					user.setStopDate(null);
					user.update();
				}
				
				boolean bool = false;
				//验证密码是否正确
				byte[] salt = Base64.decodeBase64(user.getSalt());//密码盐
				byte[] encryptedPassword = Base64.decodeBase64(user.getPassword());
				
				bool = ToolPbkdf2.authenticate(tmp.getPassword(), encryptedPassword, salt);
				
				if(bool) {
					AuthInterceptor.setCurrentUser(getRequest(), getResponse(), user, getParaToBoolean("autoLogin"));
					rtDto.setSuccess(true);
					rtDto.setMsg("登陆成功!");
				} else {
					if((user.getErrorcount() + 1) >= PropKit.getInt("errorNum")) {
						user.setStopDate(new Date());
						user.setStatus(0);
					}
					user.setErrorcount(user.getErrorcount() + 1);
					user.update();
					throw new IllegalArgumentException("用户名或密码错误!");
				}
			} else {
				throw new IllegalArgumentException("用户名或密码错误!");
			}
		} catch (Exception e) {
			rtDto.setSuccess(false);
			rtDto.setErrMsg(e.getMessage());
		} finally {
			renderJson(rtDto);
		}
	}
	
	public void toUrl() {
		render(getPara("url"));
	}
}
